package it.aqquadro.arex;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.commons.io.IOUtils;

import android.os.Build;
import android.util.Log;

import com.google.gson.Gson;

public abstract class Rexy {
	private static final String TAG = Rexy.class.getName();

	public static final String PUT_METHOD = "PUT";

	protected final Gson gson = new Gson();

	protected URL sep = null;

	protected boolean doOutput = true;

	protected HttpURLConnection conn;

	protected int chunkedStreamingMode = 0;

	protected BufferedOutputStream out = null;

	/**
	 * 
	 * @param host
	 *            host were is arex
	 * @throws MalformedURLException
	 */
	public Rexy(String host) throws MalformedURLException {

		this.sep = this.getRexysEndPoint(host);

		Log.e(TAG,
				"MalformedURLException when create the service endpoint, host is: "
						+ host);

		disableConnectionReuseIfNecessary();
	}

	/**
	 * HTTP connection reuse which was buggy pre-froyo
	 */
	protected final void disableConnectionReuseIfNecessary() {
		if (!(Integer.parseInt(Build.VERSION.SDK) > Build.VERSION_CODES.ECLAIR_MR1)) {
			System.setProperty("http.keepAlive", "false");
		}
	}

	public final void openConn() throws IOException {

		this.conn = (HttpURLConnection) this.sep.openConnection();

		this.conn.setDoOutput(this.doOutput);

		this.conn.setChunkedStreamingMode(this.chunkedStreamingMode);

	}

	public final <T> void put(T src) throws IOException {

		String jsonString = this.gson.toJson(src);

		this.conn.setRequestMethod(PUT_METHOD);

		this.write(jsonString);
	}

	protected final void write(String jsonString) throws IOException {

		if (this.out == null)
			openOutputStream();

		Log.i(TAG, "Trying to write this json: " + jsonString);

		IOUtils.write(jsonString, this.out);

	}

	private void openOutputStream() throws IOException {
		this.out = new BufferedOutputStream(this.conn.getOutputStream());
	}

	public final void closeConn() {

		IOUtils.closeQuietly(this.out);
		if (this.conn != null) {
			this.conn.disconnect();
		}
	}

	protected final URL getRexysEndPoint(String host)
			throws MalformedURLException {

		String className = this.getClass().getName();

		try {
			return new URL(host + "/a/" + className.replace(".", "/"));
		} catch (MalformedURLException e) {
			Log.e(TAG,
					"MalformedURLException when create the service endpoint, host is: "
							+ host);
			Log.e(TAG, "Message: " + e.getMessage());
			throw new MalformedURLException(e.getMessage());
		}

	}
}
